package com.ezlcp.user.service;

import com.ezlcp.commons.constant.Constants;
import com.ezlcp.commons.redis.RedisRepository;
import com.ezlcp.commons.tool.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;

/**
 * @author Elwin ZHANG
 * @description: 验证码服务
 * @date 2022/5/10 11:31
 */
@Slf4j
@Service
public class ValidateCodeServiceImpl {
    @Resource
    private RedisRepository redisRepository;

    /***
     * @description: 验证码缓存时长秒
     */
    @Value("${captcha.cache.time:120}")
    private long cacheTime;

    /**
     * 保存用户验证码
     *
     * @param deviceId  客户端生成
     * @param imageCode 验证码信息
     */
    public void saveImageCode(String deviceId, String imageCode) {
        redisRepository.setExpire(buildKey(deviceId), imageCode, cacheTime);
    }

    /**
     * 获取验证码
     *
     * @param deviceId 前端唯一标识/手机号
     */
    public String getCode(String deviceId) {
        Object obj = redisRepository.get(buildKey(deviceId));
        return obj.toString();
    }

    /**
     * 删除验证码
     *
     * @param deviceId 前端唯一标识/手机号
     */
    public void remove(String deviceId) {
        redisRepository.del(buildKey(deviceId));
    }

    /**
     * 验证验证码
     */
    public void validate(HttpServletRequest request) {
        String deviceId = request.getParameter("deviceId");
        if (StringUtils.isBlank(deviceId)) {
            throw new RuntimeException("請在請求參數中攜帶deviceId參數");
        }
        String code = this.getCode(deviceId);
        String codeInRequest;
        try {
            codeInRequest = ServletRequestUtils.getStringParameter(request, "validCode");
        } catch (ServletRequestBindingException e) {
            throw new RuntimeException("獲取驗證碼的值失敗");
        }
        if (StringUtils.isBlank(codeInRequest)) {
            throw new RuntimeException("請填寫驗證碼");
        }
        if (code == null) {
            throw new RuntimeException("驗證碼不存在或已過期");
        }
        if (!StringUtils.equals(code, codeInRequest.toLowerCase())) {
            throw new RuntimeException("驗證碼不正確");
        }
        this.remove(deviceId);
    }

    private String buildKey(String deviceId) {
        return Constants.CAPTCHA_KEY + ":T" + deviceId;
    }
}